package com.xiaoq.baiduunit.endpoint;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xiaoq.RedisTemplate4JedisCluster;
import com.xiaoq.UnitProperties;
import com.xiaoq.apis.order.ISKUApi;
import com.xiaoq.apis.order.SKUTicket4SitesVo;
import com.xiaoq.baiduunit.entity.CommunicateResponse;
import com.xiaoq.baiduunit.entity.WeatherResult;
import com.xiaoq.baiduunit.parser.CommunicateParser;
import com.xiaoq.baiduunit.service.UnitService;
import com.xiaoq.baiduunit.vo.SitesPointVo;
import com.xiaoq.baiduunit.vo.SitesPointVo.SitesPointQ;
import com.xiaoq.baiduunit.vo.SitesTicketVo;
import com.xiaoq.baiduunit.vo.WeatherVo;
import com.xiaoq.baiduunit.vo.XiaoQVo;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.JsonUtil;
import com.xiaoq.coms.util.MathUtil;
import com.xiaoq.feature.entity.ShopFoodEntity;
import com.xiaoq.feature.service.ICommentService;
import com.xiaoq.feature.service.IShopFoodService;
import com.xiaoq.feature.vo.ShopFoodVo;
import com.xiaoq.sites.entity.SitesEntity;
import com.xiaoq.sites.entity.SitesPointEntity;
import com.xiaoq.sites.service.ISitesService;
import com.xiaoq.sites.vo.QAResponseVo;
import com.xiaoq.sites.vo.SitesESDetailVo;
import com.xiaoq.sitesticket.service.ISitesTicketService;
import com.xiaoq.vo.PagingVo;
import com.xiaoq.web.HttpsRestTemplate;

import io.swagger.annotations.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by wang zhihao on 2018/4/25.
 */
@Api(tags = "小Q问答")
@RestController
@RequestMapping("/api/v1/unit")
public class UnitEndPoint {

    private Logger logger = LoggerFactory.getLogger(UnitEndPoint.class);
    private static final class WeatherUnitResponse extends GenericDataResponse<WeatherVo> {}
    private static final class SitesTicketUnitResponse extends GenericDataResponse<SitesTicketVo> {}
    private static final class SitesPointResponse extends GenericDataResponse<SitesPointVo> {}
    private static final class GossipVoResponse extends GenericDataResponse<GossipVo> {}
    private static final class ShopFoodResponse extends GenericListResponse<ShopFoodVo> {}
    private static final class QARequest extends GenericDataResponse<QAResponseVo> {}
    private static final class XiaoQDataResponse extends GenericDataResponse<XiaoQVo> {}
    
    
    @Value("${xiaoQ.qa}")
	private String qaUrl;
    
    @Autowired
    private UnitService unitService;
    @Autowired
    private UnitProperties unitProperties;
    @Autowired
    private ISitesTicketService sitesTicketService;

    @Autowired
    private ISitesService sitesService;
    
    @Autowired
    private ICommentService commentSer;
    

    @Autowired
    private RedisTemplate4JedisCluster jedisCluster;
    
    @Autowired
	private HttpsRestTemplate rest;
    
    @Autowired
	private IShopFoodService shopfoodSer;
    
    
    private final static Logger LOG = LoggerFactory.getLogger(UnitEndPoint.class);

//    @Autowired
//    private IShopFoodService shopFoodService;

    @Reference(interfaceClass=ISKUApi.class, check=false, version="1.0.0")
    private ISKUApi skuApi;

    private static final String UNIT_TOKEN_USERID_PREFIX = "unit-token-userId-";
    private static final String UNIT_SESSID_USERID_PREFIX = "unit-sessid-userId-";
    private static final String UNIT_NUM_USERID_PREFIX = "unit-num-";


    @ApiOperation(value="清空redis缓存", notes="清空redis缓存")
    @ApiResponses({
            @ApiResponse(code = 200, response = ShopFoodResponse.class, message = "清空redis缓存")
    })
    @GetMapping(value="/clearredis", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> clear(HttpServletRequest request) {

        String userId = (String) request.getAttribute("userId");
        jedisCluster.delete(UNIT_NUM_USERID_PREFIX + userId);
        jedisCluster.delete(UNIT_TOKEN_USERID_PREFIX + userId);
        jedisCluster.delete(UNIT_SESSID_USERID_PREFIX + userId);
        return GenericResponse.ok();
    }



    @ApiOperation(value="查询天气对话接口", notes="查询天气对话接口")
    @ApiResponses({
            @ApiResponse(code = 200, response = WeatherUnitResponse.class, message = "查询天气")
    })
    @GetMapping(value="/weather/{query}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> weatherQuery(@PathVariable("query") @ApiParam(value="query", required=true) String query,
                   @RequestParam(name="sessionId",defaultValue = "") @ApiParam(value="sessionId")String sessionId) {
        String errorMsg = "查询天气对话接口出错";
        try {
            WeatherVo weatherVo = new WeatherVo();

            String accessToken = unitService.getUnitAccessToken(unitProperties.getUnitWeatherAppKey(), unitProperties.getUnitWeatherAppSecret());

            if(StringUtils.isBlank(accessToken)){
                return GenericResponse.ng("获取百度api token失败");
            }
            String result = unitService.getUnitResponseString(accessToken, query,
                    sessionId, unitProperties.getUnitWeatherSeceneId());
            CommunicateParser communicateParser = new CommunicateParser();
            CommunicateResponse communicateResponse = communicateParser.parse(result);

            //设置sessionId
            weatherVo.setSessionId(communicateResponse.getSessionId());

			List<CommunicateResponse.Slots> slotsList = communicateResponse.getSlots();
			//天气问答只有2个词槽，若为size为2，则一个问答会话结束,重置会话
			if(slotsList.size() == 2){
                weatherVo.setSessionId("");
				Map<String,CommunicateResponse.Slots> map = slotsList.stream()
						.collect(Collectors.toMap(CommunicateResponse.Slots::getType, slots -> slots));
				String address = map.get("sys_loc").getOriginalWord();
				String date = map.get("sys_time").getOriginalWord();

				//查询天气接口
				String response = unitService.getWeatherResponseString(address);
                weatherVo.setMode("finish");

				WeatherResult weatherResult = JsonUtil.asObject(response,WeatherResult.class);
				if(weatherResult != null && weatherResult.containWeatherDataByKey(date)){
				    List<WeatherResult.WeatherData> weatherDataList = new ArrayList<>(weatherResult.getWeatherDataSet(date));
                    weatherVo.setWeatherDataList(weatherDataList);
                    weatherVo.setSay("");
				}else {
                    weatherVo.setSay("仅支持4天内的天气查询");
                }
			}else {
                weatherVo.setMode("append");
                weatherVo.setSay(communicateResponse.actionList.get(0).say);
			}

            return UnitEndPoint.WeatherUnitResponse.okWithData(weatherVo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return GenericResponse.ng(e.getMessage());
        }
    }

    @ApiOperation(value="查询门票接口", notes="查询门票对话接口")
    @ApiResponses({
            @ApiResponse(code = 200, response = UnitEndPoint.SitesTicketUnitResponse.class, message = "查询门票")
    })
    @GetMapping(value="/sitesticket/{query}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> sitesTicketQuery(@PathVariable("query") @ApiParam(value="query", required=true) String query,
                                          @RequestParam(name="sessionId",defaultValue = "") @ApiParam(value="sessionId")String sessionId) {
        try {
            SitesTicketVo sitesTicketVo = new SitesTicketVo();
            sitesTicketVo.setMode("finish");
            String accessToken = unitService.getUnitAccessToken(unitProperties.getUnitSitesTicketAppKey(),
                    unitProperties.getUnitSitesTicketAppSecret());

            if(StringUtils.isBlank(accessToken)){
                return GenericResponse.ng("获取百度api token失败");
            }
            String result = unitService.getUnitResponseString(accessToken, query, sessionId,
                    unitProperties.getUnitSitesTicketSeceneId());
            CommunicateParser communicateParser = new CommunicateParser();
            CommunicateResponse communicateResponse = communicateParser.parse(result);

            //设置sessionId
            sitesTicketVo.setSessionId(communicateResponse.getSessionId());
            List<CommunicateResponse.Slots> slotsList = communicateResponse.getSlots();
            Map<String,CommunicateResponse.Slots> map = slotsList.stream()
                    .collect(Collectors.toMap(CommunicateResponse.Slots::getType, slots -> slots));
            int slotSize = slotsList.size();
            //user_sites 为 百度UNIT后台自定义的词槽
            if(slotSize==1 && map.containsKey("user_sites")){ //已找到景区
                String sitesName = map.get("user_sites").getOriginalWord();

                List<SitesEntity> sitesEntityList = sitesService.findSitesFromESBySearchTxt(sitesName);
                if(CollectionUtils.isEmpty(sitesEntityList)){
                    sitesTicketVo.setSay("暂未录入该景区信息");
                    sitesTicketVo.setMode("finish");
                    return SitesTicketUnitResponse.okWithData(sitesTicketVo);
                }

                SitesEntity sitesEntity = sitesEntityList.get(0);
                List<SKUTicket4SitesVo> sitesTicketEntityList = skuApi.getTicketSKUByShopId(sitesEntity.getId());

                if(CollectionUtils.isNotEmpty(sitesTicketEntityList)) {
                    sitesTicketVo.setSay("为你找到以下门票类型: ");
                    sitesTicketVo.setTicketList(sitesTicketEntityList);
                }else{
                    sitesTicketVo.setSay("该景区暂未录入票信息");
                    sitesTicketVo.setMode("finish");
                }

                return SitesTicketUnitResponse.okWithData(sitesTicketVo);
            }

            sitesTicketVo.setSay("该景区暂未录入票信息");
            sitesTicketVo.setMode("finish");
            return SitesTicketUnitResponse.okWithData(sitesTicketVo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return GenericResponse.ng(e.getMessage());
        }
    }

    @ApiOperation(value="查询景点", notes="查询景点")
    @ApiResponses({
            @ApiResponse(code = 200, response = SitesPointResponse.class, message = "查询景点")
    })
    @GetMapping(value="/sitespoint", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public ResponseEntity<?> sitesPointQuery(@RequestParam(value = "query", required = false)
                                      @ApiParam(value="query", required = false) String query,
                                   @RequestParam(name="sitesId",required = false)
                                   @ApiParam(value="sitesId 景区ID") String sitesId) {

        SitesPointVo sitesPointVo = new SitesPointVo();
        List<SitesPointQ> sitesPointQList = new ArrayList<>();
        if(StringUtils.isAllBlank(query, sitesId)){
            sitesPointVo.setSay("小Q暂不知道怎么处理，换个问题试试");
            sitesPointVo.setSitesPoints(sitesPointQList);
            return SitesPointResponse.okWithData(sitesPointVo);
        }

        SitesPointQ sitesPointQ;
        if(StringUtils.isNotBlank(sitesId)){
            List<SitesPointEntity> sitesPointList = sitesService.findSitesPointListBySitesId(sitesId);
            if(CollectionUtils.isNotEmpty(sitesPointList)){
                for (SitesPointEntity sitesPointEntity : sitesPointList){
                    sitesPointQ = new SitesPointQ();

                    BeanUtils.copyProperties(sitesPointEntity, sitesPointQ);
                    sitesPointQList.add(sitesPointQ);
                }
                sitesPointVo.setSay("");
                sitesPointVo.setSitesPoints(sitesPointQList);
                return SitesPointResponse.okWithData(sitesPointVo);
            }
        }

        if(StringUtils.isNotBlank(query)){
            PagingVo pagingVo = new PagingVo();
            pagingVo.setPs(10);
            //Es 分页从1开始
            pagingVo.setPn(1);
            List<SitesPointEntity> sitesPointList = sitesService.findSitesPointFromEsByName(query, pagingVo);
            if(CollectionUtils.isNotEmpty(sitesPointList)){
                for (SitesPointEntity sitesPointEntity : sitesPointList){
                    sitesPointQ = new SitesPointQ();
                    BeanUtils.copyProperties(sitesPointEntity, sitesPointQ);
                    sitesPointQList.add(sitesPointQ);
                }
                sitesPointVo.setSitesPoints(sitesPointQList);
                sitesPointVo.setSay("");
                return SitesPointResponse.okWithData(sitesPointVo);
            }
        }

        if(CollectionUtils.isNotEmpty(sitesPointQList)){
            sitesPointVo.setSay("");
            sitesPointVo.setSitesPoints(sitesPointQList);
            return SitesPointResponse.okWithData(sitesPointVo);
        }

        sitesPointVo.setSay("让小Q想想，您也可以换个问题试试");
        sitesPointVo.setSitesPoints(sitesPointQList);
        return SitesPointResponse.okWithData(sitesPointVo);
    }

    public static class GossipVo {
        @ApiModelProperty(name = "sessionId", value = "当sessionId", position=10)
        public String sessionId;
        @ApiModelProperty(name = "say", value = "say", position=20)
        public String say;
        @ApiModelProperty(name = "foodList", value = "", position=30)
        public List<ShopFoodVo> foodList = new ArrayList<>();
    }

    @ApiOperation(value="闲聊对话接口", notes="闲聊对话接口")
    @ApiResponses({
            @ApiResponse(code = 200, response = GossipVoResponse.class, message = "闲聊对话接口")
    })
    @GetMapping(value="/gossip/{query}", produces={MediaType.APPLICATION_JSON_UTF8_VALUE})
    public Object gossip(@PathVariable("query") @ApiParam(value="query", required=true) String query,
                         @RequestParam(name="sessionId",defaultValue = "") @ApiParam(value="sessionId")String sessionId) {
        try {

            String accessToken = unitService.getUnitAccessToken(unitProperties.getUnitWeatherAppKey(), unitProperties.getUnitWeatherAppSecret());

            if(StringUtils.isBlank(accessToken)){
                return GenericResponse.ng("获取百度api token失败");
            }
            String result = unitService.getUnitResponseString(accessToken, query,
                    sessionId, "100");
            CommunicateParser communicateParser = new CommunicateParser();
            CommunicateResponse communicateResponse = communicateParser.parse(result);
            GossipVo gossipVo = new GossipVo();
            gossipVo.sessionId = communicateResponse.sessionId;
            if(CollectionUtils.isNotEmpty(communicateResponse.getActionList())){
                gossipVo.say = communicateResponse.getActionList().get(0).say;
            }
            return GossipVoResponse.okWithData(gossipVo);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return GenericResponse.ng(e.getMessage());
        }
    }
    
	@ApiOperation(value = "小Q问答接口", notes = "小Q问答接口")
	@ApiResponses({ @ApiResponse(code = 200, response = XiaoQDataResponse.class, message = "小Q问答接口") })
	@GetMapping(value = "/qa", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
	public ResponseEntity<?> xiaoQQA(
			@RequestParam(name = "query", required = true) @ApiParam(value = "query", required = true) String query,
			@RequestParam(name = "sessionId", defaultValue = "") @ApiParam(value = "sessionId") String sessionId,
			@RequestParam(value = "localLongitude", required = false) @ApiParam(value = "当前经度", required = false) Double localLongitude,
			@RequestParam(value = "localLatitude", required = false) @ApiParam(value = "当前纬度", required = false) Double localLatitude) {
		String url = qaUrl + query;
		String respStr = get(url);
		XiaoQVo xiaoQVo = new XiaoQVo();
		GossipVo gossipVo = getBaiduUnit(query, sessionId);
		sessionId = gossipVo.sessionId;
		if (StringUtils.isBlank(respStr)) {
			// 启动闲聊
			xiaoQVo.setSay(gossipVo.say);
			xiaoQVo.setTagetType("00");
			xiaoQVo.setSessionId(sessionId);
			return XiaoQDataResponse.okWithData(xiaoQVo);
		}
		QARequest qaResult = JsonUtil.asObject(respStr, QARequest.class);
		QAResponseVo qaResponse = qaResult.getData();
		String tagetType = qaResponse.getTagetType();
		String sentence = qaResponse.getSentence();
		LOG.info("**************"+sentence);
		
		if (StringUtils.isBlank(tagetType) && "next".equals(sentence)) {
			// 启动闲聊
			xiaoQVo.setSay(gossipVo.say);
			xiaoQVo.setTagetType("00");
			xiaoQVo.setSessionId(sessionId);
			return XiaoQDataResponse.okWithData(xiaoQVo);
		} else {
			if ("10".equals(tagetType)) {
				List<SitesESDetailVo> sitesESDetailVoList = new ArrayList<>();
				if ("wan".equals(sentence)) {
					 sitesESDetailVoList = findSitesESVoList(query, null, localLongitude, localLatitude);

				} else {
					 sitesESDetailVoList = findSitesESVoList(null, sentence, localLongitude, localLatitude);

				}
				if(sitesESDetailVoList!=null&&sitesESDetailVoList.size()!=0){
					xiaoQVo.setSitesESDetailVoList(sitesESDetailVoList);
					xiaoQVo.setSay("小Q为你找到了！");
					xiaoQVo.setTagetType("10");
				}else{
					xiaoQVo.setSay(gossipVo.say);
					xiaoQVo.setTagetType("00");
				}
				

			} else if ("11".equals(tagetType)) {
				List<SitesPointQ> sitesPointQList =  new ArrayList<>();
				if ("wan".equals(sentence)) {
					sitesPointQList = findSitesPointESVoList(query, null,localLongitude,localLatitude);

				} else {
					sitesPointQList = findSitesPointESVoList(null, sentence,localLongitude,localLatitude);
				}
				if(sitesPointQList!=null&&sitesPointQList.size()!=0){
					xiaoQVo.setSitesPointQList(sitesPointQList);
					xiaoQVo.setSay("小Q为你找到了！");
					xiaoQVo.setTagetType("11");
				}else{
					xiaoQVo.setTagetType("00");
					xiaoQVo.setSay(gossipVo.say);
				}

			} else if ("12".equals(tagetType)) {
				List<ShopFoodVo> shopFoodVoList = new ArrayList<>();
				PagingVo pagingVo = new PagingVo();
				pagingVo.setPn(1);
				pagingVo.setPs(10);
				if ("chi".equals(sentence)) {
					shopFoodVoList = findShopFoodVoList(query, null, localLongitude, localLatitude, pagingVo);
					shopFoodVoList = sortShopFood(shopFoodVoList, localLongitude, localLatitude);

				} else {
					shopFoodVoList = findShopFoodVoList(null, sentence, localLongitude, localLatitude, pagingVo);
					shopFoodVoList = sortShopFood(shopFoodVoList, localLongitude, localLatitude);
				}
				if(shopFoodVoList!=null&&shopFoodVoList.size()!=0){
					xiaoQVo.setShopFoodVoList(shopFoodVoList);
					xiaoQVo.setTagetType("12");
					xiaoQVo.setSay("小Q为你找到了！");
				}else{
					xiaoQVo.setTagetType("00");
					xiaoQVo.setSay(gossipVo.say);
				}

			} else {
				xiaoQVo.setTagetType("00");
				xiaoQVo.setSay(gossipVo.say);
				xiaoQVo.setSessionId(sessionId);
				return XiaoQDataResponse.okWithData(xiaoQVo);
			}
			xiaoQVo.setSessionId(sessionId);
			return XiaoQDataResponse.okWithData(xiaoQVo);
		}

	}
	
	private List<ShopFoodVo> sortShopFood(List<ShopFoodVo> shopFoodVoList,Double lng,Double lat){
		List<ShopFoodVo>  shopFoodList = new ArrayList<>();
		if(shopFoodVoList==null||shopFoodVoList.size()==0){
			return shopFoodVoList;
		}
		for(int i=0;i<shopFoodVoList.size();i++){
			ShopFoodVo shopFoodVo = shopFoodVoList.get(i);
			String id = shopFoodVo.getId();
			long commentNums = commentSer.findCommentNums(id);
			shopFoodVo.setCommentNums(commentNums);
			if(lng!=null&&lat!=null&&lng!=0.00&&lat!=0.00){
				Double shopLongitude = shopFoodVo.getLongitude();
				Double shopLatitude = shopFoodVo.getLatitude();
				Double distance = MathUtil.distance(lng, lat, shopLongitude, shopLatitude);
				shopFoodVo.setDistance(distance);
				String distanceString = MathUtil.distance(distance);
				shopFoodVo.setDistanceString(distanceString);
			}
			shopFoodList.add(shopFoodVo);
		}
		if (shopFoodVoList != null && shopFoodVoList.size() > 1) {

			Collections.sort(shopFoodVoList, new Comparator<ShopFoodVo>() {

				@Override
				public int compare(ShopFoodVo shopFoodVo1, ShopFoodVo shopFoodVo2) {
					Double status1 = shopFoodVo1.getAvgScore() - shopFoodVo2.getAvgScore();
					if (status1 == 0.0) {
						Double status2 = shopFoodVo1.getDistance() - shopFoodVo2.getDistance();
						if (status2 > 0.0) {
							return 1;
						} else {
							return -1;
						}
					} else {
						if (status1 > 0.0) {
							return -1;
						} else {
							return 1;
						}
					}
				}
			});
		}
		
		return shopFoodVoList;
	}
	
	private String get(String url) {
		HttpEntity<String> reqEntity = new HttpEntity<String>(null, defaultHeaders());
		ResponseEntity<String> resp = null;
		String msg = "调用Qa服务出问题";
		try {
			resp = rest.exchange(new URI(url),
					HttpMethod.GET,
					reqEntity,
					String.class);
		} catch (Exception e) {
			LOG.error(msg, e);
			
		}
		if (resp != null && resp.getStatusCodeValue() == HttpStatus.OK.value()) {
			return resp.getBody();
		}
		return null;
		
	}
	private HttpHeaders defaultHeaders() {
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
		headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
		return headers;
	}
	
	private GossipVo getBaiduUnit(String query,String sessionId){
		GossipVo gossipVo = new GossipVo();
		try {

            String accessToken = unitService.getUnitAccessToken(unitProperties.getUnitWeatherAppKey(), unitProperties.getUnitWeatherAppSecret());
            String result = unitService.getUnitResponseString(accessToken, query,
                    sessionId, "100");
            CommunicateParser communicateParser = new CommunicateParser();
            CommunicateResponse communicateResponse = communicateParser.parse(result);
           
            gossipVo.sessionId = communicateResponse.sessionId;
            if(CollectionUtils.isNotEmpty(communicateResponse.getActionList())){
                gossipVo.say = communicateResponse.getActionList().get(0).say;
            }
            return gossipVo;
        } catch (Exception e) {
            logger.error(e.getMessage());
            gossipVo.say = "小Q在休息奥，等会再陪你玩好不好嘛！";
            return gossipVo;
        }
		
	}
	
	/**
	 * 
	 * @param query  关键词
	 * @param sitesId  景区Id
	 * @return
	 */
	private List<SitesPointQ>  findSitesPointESVoList(String query,String sitesId,Double lng,Double lat){
		List<SitesPointQ> sitesPointQList = new ArrayList<>();
        if(StringUtils.isNotBlank(sitesId)){
            List<SitesPointEntity> sitesPointList = sitesService.findSitesPointListBySitesId(sitesId);
            sitesPointQList = sortSitesPointQ(sitesPointList, lng, lat);
        }

        if(StringUtils.isNotBlank(query)){
            PagingVo pagingVo = new PagingVo();
            pagingVo.setPs(10);
            //Es 分页从1开始
            pagingVo.setPn(1);
            List<SitesPointEntity> sitesPointList = sitesService.findSitesPointFromEsByName(query, pagingVo);
            sitesPointQList = sortSitesPointQ(sitesPointList, lng, lat);
        }

        return sitesPointQList;
	}
	
	private List<SitesPointQ> sortSitesPointQ(List<SitesPointEntity> sitesPointList,Double lng,Double lat){
		List<SitesPointQ> sitesPointQList = new ArrayList<>();
		SitesPointQ sitesPointQ;
		if(CollectionUtils.isNotEmpty(sitesPointList)){
            for (SitesPointEntity sitesPointEntity : sitesPointList){
                sitesPointQ = new SitesPointQ();

                BeanUtils.copyProperties(sitesPointEntity, sitesPointQ);
                if(lng!=null&&lat!=null&&lng!=0.00&&lat!=0.00){
					Double shopLongitude = sitesPointQ.getLongitude();
					Double shopLatitude = sitesPointQ.getLatitude();
					Double distance = MathUtil.distance(lng, lat, shopLongitude, shopLatitude);
					sitesPointQ.setDistance(distance);
					String distanceString = MathUtil.distance(distance);
					sitesPointQ.setDistanceString(distanceString);
				}
                sitesPointQList.add(sitesPointQ);
            }
        }
        if(sitesPointQList!=null&&sitesPointQList.size()>1){
			Collections.sort(sitesPointQList, new Comparator<SitesPointQ>() {
				
				@Override
				public int compare(SitesPointQ sitesPointVo1, SitesPointQ sitesPointVo2) {
					int status1 = sitesPointVo1.getRecIndex()-sitesPointVo2.getRecIndex();
					if(status1 == 0){
						Double status2 = sitesPointVo1.getDistance()-sitesPointVo2.getDistance();
						if(status2>0){
							return 1;
						}else{
							return -1;
						}
					}else {
						if(status1>0){
							return -1;
						}else{
							return 1;
						}
					}
				}
			});
		}
		
        return sitesPointQList;
	}
	
	/**
	 * 
	 * @param k  景区的关键词
	 * @param city  城市code
	 * @param lng 当前经度
	 * @param lat
	 * @return
	 */
	private List<SitesESDetailVo>  findSitesESVoList(String k,String city,Double lng,Double lat){
		int page = 0, size = 10;
		if(StringUtils.isBlank(city) || !StringUtils.isNumeric(city)) {
			throw new RuntimeException("城市code错误");
		}

		List<SitesESDetailVo> sitesESDetailVoList = new ArrayList<>();
		List<SitesEntity> sitesEntityList;
		if(k!=null && StringUtils.isNotBlank(k.trim())) {
			sitesEntityList = sitesService.findSitesFromESByCityCodeAndKeyWord(city, k, page, size);
		}else {
			//处理 k 为 null,直接从redis/mongo里取
			sitesEntityList = sitesService.findSitesListbyZoneCity(city,null);
		}

		if(CollectionUtils.isEmpty(sitesEntityList)){
			//直接取贵阳的数据
			sitesEntityList = sitesService.findSitesListbyZoneCity("520100",null);
		}

		if(CollectionUtils.isNotEmpty(sitesEntityList)) {
			SitesESDetailVo sitesESDetailVo;
			for (SitesEntity sitesEntity : sitesEntityList) {
				sitesESDetailVo = new SitesESDetailVo();
				sitesESDetailVo.setCenterLatitude(sitesEntity.getCenterLatitude());
				sitesESDetailVo.setCenterLongitude(sitesEntity.getCenterLongitude());
				sitesESDetailVo.setDistance(MathUtil.distance(lng,lat,sitesEntity.getMainEntryLongitude(),sitesEntity.getMainEntryLatitude()));  //根据经纬度计算距离  TODO
				sitesESDetailVo.setId(sitesEntity.getId());
				sitesESDetailVo.setImgUrl(sitesEntity.getMainImgUrl());
				sitesESDetailVo.setIntroduction(sitesEntity.getIntroduction());
				sitesESDetailVo.setLevels(sitesEntity.getLevels());
				sitesESDetailVo.setMainEntryLatitude(sitesEntity.getMainEntryLatitude());
				sitesESDetailVo.setMainEntryLongitude(sitesEntity.getMainEntryLongitude());
				sitesESDetailVo.setName(sitesEntity.getName());
				sitesESDetailVo.setShortName(sitesEntity.getShortName());
				sitesESDetailVo.setTags(sitesEntity.getTags());
				sitesESDetailVo.setMaxRadius(sitesEntity.getMaxRadius());
				sitesESDetailVo.setStatus(sitesEntity.getStatus());
				sitesESDetailVo.setType(10);  // 暂时只搜景区    TODO
				sitesESDetailVo.setZoneCode(sitesEntity.getZoneCity());  // 暂时只搜城市景区    TODO
				sitesESDetailVo.setDistanceString(MathUtil.distance(sitesESDetailVo.getDistance()));

				sitesESDetailVoList.add(sitesESDetailVo);
			}

			//升序排序
			sitesESDetailVoList.sort((sites1,sites2) -> sites1.getDistance().compareTo(sites2.getDistance()));
		}

		return sitesESDetailVoList;
		
	}
	
	/**
	 * 根据关键词和景区Id查询必吃列表
	 * @param query  关键词
	 * @param sitesId  景区Id
	 * @param localLongitude 当前经度
	 * @param localLatitude  当前维度
	 * @param pagingVo
	 * @return
	 */
	private List<ShopFoodVo> findShopFoodVoList(String query,String condition,Double localLongitude,Double localLatitude,PagingVo pagingVo){
		List<ShopFoodVo> shopFoodList = new ArrayList<>();
		if(StringUtils.isNotBlank(query)){
			shopFoodList = findShopFoodVoByES(query, localLongitude, localLatitude, pagingVo);
		}
		if(StringUtils.isNotBlank(condition)){
			SitesEntity sites = sitesService.findById(condition);
			if(sites!=null){
				Double longitude = sites.getCenterLongitude();
				Double latitude = sites.getCenterLatitude();
				shopFoodList = findShopFoodVoByMongo(longitude,latitude, localLongitude, localLatitude, pagingVo);
			}else{
				shopFoodList = findShopFoodVoByMongoByCity(condition, pagingVo);
			}
			
			
		}
		return shopFoodList;
		
	}
	
	private List<ShopFoodVo> findShopFoodVoByES(String query,Double localLongitude,Double localLatitude,PagingVo pagingVo){
		List<ShopFoodEntity> shopFoodList = shopfoodSer.findShopFoodFromEsByText(query, pagingVo);
		List<ShopFoodVo> shopFoodVoList = new ArrayList<>();
		ShopFoodVo shopFoodVo = null;
		for(ShopFoodEntity shopFood:shopFoodList){
			shopFoodVo = new ShopFoodVo();
			BeanUtils.copyProperties(shopFood, shopFoodVo);
			if(localLongitude!=null&&localLatitude!=null&&localLongitude!=0.00&&localLatitude!=0.00){
				Double shopLongitude = shopFoodVo.getLongitude();
				Double shopLatitude = shopFoodVo.getLatitude();
				Double distance = MathUtil.distance(localLongitude, localLatitude, shopLongitude, shopLatitude);
				shopFoodVo.setDistance(distance);
				String distanceString = MathUtil.distance(distance);
				shopFoodVo.setDistanceString(distanceString);
			}
			shopFoodVoList.add(shopFoodVo);
		}
		
		return shopFoodVoList;
	}
	
	private List<ShopFoodVo> findShopFoodVoByMongoByCity(String cityCode,PagingVo pvo){
		List<ShopFoodEntity> shopFoodList = shopfoodSer.findShopFoodListByCity(cityCode, pvo);
		List<ShopFoodVo> shopFoodVoList = new ArrayList<>();
		ShopFoodVo shopFoodVo = null;
		for(ShopFoodEntity shopFood:shopFoodList){
			shopFoodVo = new ShopFoodVo();
			BeanUtils.copyProperties(shopFood, shopFoodVo);
			shopFoodVoList.add(shopFoodVo);
		}
		return shopFoodVoList;
	}
	
	private List<ShopFoodVo> findShopFoodVoByMongo(Double longitude,Double latitude,Double localLongitude,Double localLatitude,PagingVo pvo){
		List<ShopFoodEntity> shopFoodList = shopfoodSer.findShopFoodList(longitude, latitude, localLongitude,localLatitude,pvo);
		List<ShopFoodVo> shopFoodVoList = new ArrayList<>();
		ShopFoodVo shopFoodVo = null;
		for(ShopFoodEntity shopFood:shopFoodList){
			shopFoodVo = new ShopFoodVo();
			BeanUtils.copyProperties(shopFood, shopFoodVo);
			if(localLongitude!=null&&localLatitude!=null&&localLongitude!=0.00&&localLatitude!=0.00){
				Double shopLongitude = shopFoodVo.getLongitude();
				Double shopLatitude = shopFoodVo.getLatitude();
				Double distance = MathUtil.distance(localLongitude, localLatitude, shopLongitude, shopLatitude);
				shopFoodVo.setDistance(distance);
				String distanceString = MathUtil.distance(distance);
				shopFoodVo.setDistanceString(distanceString);
			}
			shopFoodVoList.add(shopFoodVo);
		}
		
		return shopFoodVoList;
	}

}
